#pragma once

#include "genericproperty.h"
#include <QList>

namespace VrDataCore
{
	template <typename T>
	class VRDATACORE_EXPORT IntProperty : public GenericProperty<T,int>
	{
	public:
		typedef GenericProperty<T,int> BaseClass;
		typedef BaseClass::SetFun IntPropertySetFun;
		typedef BaseClass::GetFun IntPropertyGetFun;
		IntProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,IntPropertySetFun set, IntPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(int str)
		{
			GenericProperty<T,int>::setValue(str);
		}

		virtual bool fromString(const QString& value)
		{
			int valueint = value.toInt();
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			int returnint = GenericProperty<T,int>::getValue();
			return QString::number(returnint);
		}
	protected:
		virtual ~IntProperty() { }
	};
	//-----------------------------------------------------------------------------------------------
	template <typename T>
	class VRDATACORE_EXPORT FloatProperty : public GenericProperty<T,float>
	{
	public:
		typedef GenericProperty<T,float> BaseClass;
		typedef BaseClass::SetFun FloatPropertySetFun;
		typedef BaseClass::GetFun FloatPropertyGetFun;
		FloatProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,FloatPropertySetFun set, FloatPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(float str)
		{
			GenericProperty<T,float>::setValue(str);
		}

		virtual bool fromString(const QString& value)
		{
			float valueint = value.toFloat();
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			float returnint = GenericProperty<T,float>::getValue();
			return QString::number(returnint);
		}
	protected:
		virtual ~FloatProperty() { }
	};
	//-----------------------------------------------------------------------------------------------
	template <typename T>
	class VRDATACORE_EXPORT DoubleProperty : public GenericProperty<T,double>
	{
	public:
		typedef GenericProperty<T,double> BaseClass;
		typedef BaseClass::SetFun DoublePropertySetFun;
		typedef BaseClass::GetFun DoublePropertyGetFun;
		DoubleProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,DoublePropertySetFun set, DoublePropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(double str)
		{
			GenericProperty<T,double>::setValue(str);
		}

		virtual bool fromString(const QString& value)
		{
			double valueint = value.toDouble();
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			double returnint = GenericProperty<T,double>::getValue();
			return QString::number(returnint);
		}
	protected:
		virtual ~DoubleProperty() { }
	};
	//-----------------------------------------------------------------------------------------------
	template <typename T>
	class VRDATACORE_EXPORT IntListProperty : public GenericProperty<T,QList<int>>
	{
	public:
		typedef GenericProperty<T,QList<int>> BaseClass;
		typedef BaseClass::SetFun IntListPropertySetFun;
		typedef BaseClass::GetFun IntListPropertyGetFun;
		IntListProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,IntListPropertySetFun set, IntListPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(QList<int> val)
		{
			GenericProperty<T,QList<int>>::setValue(val);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(",",QString::SkipEmptyParts);
			QList<int> valueint;
			for(int i=0;i<list.size();++i)
			{
				valueint.push_back(list.at(i).toInt());
			}
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			QList<int> list = GenericProperty<T,QList<int>>::getValue();
			QString returnstring = "";
			for(int i=0;i<list.size();++i)
			{
				returnstring = returnstring +","+QString::number(list.at(i));
			}
			return returnstring;
		}
	protected:
		virtual ~IntListProperty() { }
	};
	//-----------------------------------------------------------------------------------------------
	template <typename T>
	class VRDATACORE_EXPORT FloatListProperty : public GenericProperty<T,QList<float>>
	{
	public:
		typedef GenericProperty<T,QList<float>> BaseClass;
		typedef BaseClass::SetFun FloatListPropertySetFun;
		typedef BaseClass::GetFun FloatListPropertyGetFun;
		FloatListProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,FloatListPropertySetFun set, FloatListPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(QList<float> val)
		{
			GenericProperty<T,QList<float>>::setValue(val);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(",",QString::SkipEmptyParts);
			QList<float> valueint;
			for(int i=0;i<list.size();++i)
			{
				valueint.push_back(list.at(i).toFloat());
			}
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			QList<float> list = GenericProperty<T,QList<float>>::getValue();
			QString returnstring = "";
			for(int i=0;i<list.size();++i)
			{
				returnstring = returnstring +","+QString::number(list.at(i));
			}
			return returnstring;
		}
	protected:
		virtual ~FloatListProperty() { }
	};
	//-----------------------------------------------------------------------------------------------
	template <typename T>
	class VRDATACORE_EXPORT DoubleListProperty : public GenericProperty<T,QList<double>>
	{
	public:
		typedef GenericProperty<T,QList<double>> BaseClass;
		typedef BaseClass::SetFun DoubleListPropertySetFun;
		typedef BaseClass::GetFun DoubleListPropertyGetFun;
		DoubleListProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,DoubleListPropertySetFun set, DoubleListPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(QList<double> val)
		{
			GenericProperty<T,QList<double>>::setValue(val);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(",",QString::SkipEmptyParts);
			QList<double> valueint;
			for(int i=0;i<list.size();++i)
			{
				valueint.push_back(list.at(i).toDouble());
			}
			setValue(valueint);
			return true;
		}
		virtual const QString toQString() const
		{
			QList<double> list = GenericProperty<T,QList<double>>::getValue();
			QString returnstring = "";
			for(int i=0;i<list.size();++i)
			{
				returnstring = returnstring +","+QString::number(list.at(i));
			}
			return returnstring;
		}
	protected:
		virtual ~DoubleListProperty() { }
	};
}